# _*_coding:utf-8_*_
from ATS.instrumentDriver import InstGen
import time
from utils.singleton_util import singleton


@singleton
class VNA_N5225B(InstGen.VNA):
    def __init__(self, name):
        super().__init__(name)
        self.channel_id = 1

    def set_data_format(self, default="ascii"):
        self.handler.write(f"FORM {default}")

    def init_macro(self):
        cmd = "SYST:SHOR1:EXEC;*opc?"
        return self.handler.ask(cmd)

    def get_points(self):
        return self.handler.ask("SENSe:SWEep:POINts?")

    def __auto_scale_all(self):
        self.handler.write("DISP:WIND:Y:AUTO")

    def get_snp_data(self):
        self.handler.ask("TRIG:SOUR IMM;*OPC?")
        self.handler.ask("SENS:SWE:MODE SING;*OPC?")
        self.handler.ask("MMEM:STOR:TRAC:FORM:SNP RI;*OPC?")
        self.handler.ask("format:data ascii;*OPC?")
        return self.handler.query_binary_values("CALC:MEAS1:DATA:SNP? 4").split(",")

    def get_x_y_trace_data(self, trace_num=1):
        # CALC: MEAS1:X?
        # CALCulate1: MEASure1:DATA: FDATA?
        self.handler.write(f"display:window1:trace{trace_num}:select")
        # x轴的数据
        x_data = self.handler.ask(f"CALC:MEAS{trace_num}:X?").strip().split(",")
        self.wait()
        # y轴的数据
        y_data = self.handler.ask(f"CALCulate:MEASure{trace_num}:DATA:FDATA?").strip().split(",")
        self.wait()
        if all([x_data, y_data]):
            return x_data, y_data

    def get_specific_marker_value(self, trace_num):
        self.handler.write(f"CALC:PAR:MNUM {trace_num}")
        self.handler.write(f"CALC:MEAS{trace_num}:MARK:X 100Mhz")
        self.handler.write(f"calculate:measure{trace_num}:marker1 on")
        # self.wait()
        x_data = self.handler.ask("CALCulate:MARKer1:X?").strip()
        y_data = self.handler.ask("calculate:marker1:y?").strip().split(",")[0]
        return x_data, y_data

    def search_bw(self, target_value):
        # SYST:MEAS:CAT?trace的number
        # display:window1:trace2:select
        self.__auto_scale_all()
        self.wait()
        # time.sleep(0.2)
        self.handler.ask("SYST:MEAS:CAT?")
        self.handler.write("CALC:PAR:MNUM 1")
        self.handler.write("CALC:MARK:REF:X 1e9")
        self.handler.write("CALC:MEAS1:MARK:REF ON")
        self.handler.write("calculate:measure1:marker1 on")
        self.handler.write("calculate:measure1:marker1:delta on")
        self.handler.write(f"calculate:measure1:marker1:function:target:value {target_value}")
        self.handler.write("calculate:measure1:marker1:function:execute TARGet")
        self.handler.write("CALC:MEAS1:MARK1:FUNC:TARG:TRAN BOTH")
        self.wait()
        x_data = self.handler.ask("CALCulate:MARKer1:X?").strip()
        y_data = self.handler.ask("calculate:marker1:y?").strip().split(",")[0]
        return x_data, y_data

    def _save_snp_data(self, n=3):
        self.handler.ask("MMEM:STOR:TRAC:FORM:SNP RI;*OPC?")
        self.handler.ask("format:data ascii;*OPC?")
        content_list = self.handler.ask(f"CALC:MEAS:DATA:SNP? {n}").strip().split(",")
        data_length = int(n) * 6 + 1
        len_group = int(len(content_list) / data_length)
        raw_data_list = [[] for _ in range(data_length)]
        for current_len in range(len_group):
            for group_id in range(data_length):
                raw_data_list[group_id].append(content_list[current_len + group_id * len_group])
        freq_list = raw_data_list.pop(0)
        total_content = "# Hz S RI R 50.000000\n"
        for group in range(len_group):
            group_content = f"{freq_list[group]} "
            for group_id in range(data_length - 1):
                group_content += f" {raw_data_list[group_id][group]}"
                if (group_id + 1) % 6 == 0:
                    group_content += "\n"
            total_content += group_content

        print("total_content", total_content)

    # 调起程序
    def start_trigger(self):
        # self.handler.write("CALC:MEAS:MARK:FUNC:DOM:USER:RANG 1")
        # self.handler.write("CALC:MEAS:MARK:FUNC:DOM:USER:START 1e10")
        # self.handler.write("CALC:MEAS:MARK:FUNC:DOM:USER:STOP 5e10")
        cmd = "SYST:SHOR2:EXEC;*opc?"
        result = self.handler.ask(cmd).strip()
        self.wait()
        return result

    def wait(self):
        self.handler.write("*WAI")

    def __enable_marker_max(self, marker_id, trace_id=1):
        # 查询marker是否开启
        state = int(self.handler.ask(f"CALC{self.channel_id}:MEAS{trace_id}:MARK{marker_id}?").strip())
        if not state:
            self.handler.write(f"CALC{self.channel_id}:MEAS{trace_id}:MARK:COUP OFF")
            self.handler.write(f"CALC{self.channel_id}:MEAS{trace_id}:MARK{marker_id} ON")
        # 将marker移动到最大值的点
        self.handler.ask(f"CALC{self.channel_id}:MEAS{trace_id}:MARK{marker_id}:FUNC:EXEC MAX;*OPC?")
        time.sleep(0.2)
        self.handler.write(f"CALC{self.channel_id}:MEAS{trace_id}:MARK{marker_id}:FUNC:TRAC ON")

    def cf_center(self, bw_search, trace_id=1):
        self.__enable_marker_max(1, trace_id)
        bw_search_value = (self.handler.ask(f"CALC{self.channel_id}:MEAS{trace_id}:MARK:BWID:THR?").strip())
        if bw_search_value != bw_search:
            self.handler.ask(f"CALC{self.channel_id}:MEAS{trace_id}:MARK:BWID:THR {bw_search};*opc?")
            # self._init_trigger()
        state = int(self.handler.ask(f"CALC{self.channel_id}:MEAS{trace_id}:MARK1:BWID?").strip())
        if not state:
            self.handler.write(f"CALC{self.channel_id}:MEAS{trace_id}:MARK1:BWID ON")
            time.sleep(0.2)
        raw_data = self.handler.ask(f"CALC{self.channel_id}:MEAS{trace_id}:MARK1:BWID:DATA?").strip().split(',')
        loss = round(float(raw_data[-1]), 3)  # loss值
        bw1 = round(float(raw_data[0]) * 1e-6, 3)  # bandwidth unit = MHz
        f1 = round(float(raw_data[1]) * 1e-6, 3)  # center freq unit = MHz
        quality = round(float(raw_data[2]), 3)  # Q值
        flow = round(f1 - (bw1 / 2), 3)  # test fLow
        fhigh = round(f1 + (bw1 / 2), 3)  # test fHigh
        return bw1, f1, flow, fhigh, quality, loss
